#ifndef MASTER_H_
#define MASTER_H_

#include <Poco/Net/DialogSocket.h>
#include <string>
#include "command/commandfactory.h"
#include <Poco/File.h>
#include <Poco/Runnable.h>

using Poco::Runnable;
using Poco::Net::DialogSocket;
using std::string;
using Commands::CommandFactory;
using Poco::File;

/**
 * This class represents the master.
 *
 */
class Master : public Runnable{
public:
	/**
	 * Create a new Master.
	 *
	 */
	Master();

	/**
	 * Destructor
	 */
	virtual ~Master();

	/**
	 * Connect to another host/port.
	 *
	 * @param host IP of the slave
	 * @param port port of the slave
	 * @exception ConnectionException when the connection could not be established
	 */
	void connect(string const& host, int port);

	/**
	 * Break the current connection.
	 *
	 * @exception ConnectionException where there if no active connection to disconnect from
	 */
	void disconnect();

	/**
	 * Send a message and return one.
	 *
	 * @param msg the message to send
	 * @return the response
	 */
	string communicate(string const& msg);

	/**
	 * Get the local host name for the current connection
	 *
	 * @return local host name
	 */
	string getLocalHostname() const;

	/**
	 * Get the connected host name for the current connection
	 *
	 * @return connected host name
	 */
	string getConnectedHostname() const;

	/**
	 * Leave the slave. It's a loser anyway...
	 */
	void leave();

	/**
	 * Join with a slave
	 *
	 * @param host hostname/IP of the slave
	 * @param port port of the slave
	 */
	void join(string const& host, int port);

	/**
	 * Transfer a file to the slave
	 *
	 * @param filename The path to the file you want to transfer
	 */
	void put( string const& fileName );


	/**
	 * Get a file from the slave
	 *
	 * @param filename The path to the file you want to transfer
	 * @return Whether the file could be getted.
	 */
	bool get(string const& filename, File file);

	/**
	 * Execute a shell command on the slave
	 *
	 * @param cmdline Commandline to be run
	 */
	void command(string const& cmdline);
	
	/**
	 * Executes a certain command denoted by string (if implemented)
	 *
	 */
	void executeCommand( Command* command);

	void run();

private:

	//! socket to use to communicate with the slave
	DialogSocket * fSocket;
	
	//! The commands registered with this Master
	CommandFactory * fCommFac;
};

#endif /*MASTER_H_*/
